package com.weiun.common.core.aop;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson.JSON;
import com.weiun.common.base.bean.ParamBean;
import com.weiun.common.base.bean.ResultBean;
import com.weiun.common.base.exception.NoAuthException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.InvocationTargetException;

/**
 * The type Exception handler.
 * 身份验证
 *
 * @author Weiun
 */
public class AuthHandler implements ThrowsAdvice {

    private static final Log logger = LogFactory.get();


    public ResultBean around(JoinPoint joinPoint) throws Throwable {
        ParamBean paramBean = null;
        ResultBean resultBean;
        String className;
        String methodName;
        Object[] param = null;
        ProceedingJoinPoint proceedingJoinPoint = null;
        try {
            proceedingJoinPoint = (ProceedingJoinPoint) joinPoint;
            methodName = proceedingJoinPoint.getSignature().getName();
            param = proceedingJoinPoint.getArgs();
            if (param != null && param.length == 1) {
                Object object = param[0];
                paramBean = (object instanceof ParamBean) ? (ParamBean) object : null;
            }
            Class<?> aClass = joinPoint.getTarget().getClass();
            AuthCheck authCheck = aClass.getAnnotation(AuthCheck.class);
            if (authCheck == null) {
                authCheck = aClass.getMethod(methodName, ParamBean.class).getAnnotation(AuthCheck.class);
            }
            if (authCheck != null) {
                if (paramBean == null || StrUtil.isEmpty(paramBean.getUid())) {
                    throw new NoAuthException();
                }
                String[] identity = authCheck.identity();
                if (identity.length > 0 && !ArrayUtil.contains(identity, paramBean.getIdentity())) {
                    throw new NoAuthException();
                }
            }
            resultBean = (ResultBean) proceedingJoinPoint.proceed();
        } catch (Throwable e) {
            if (e instanceof InvocationTargetException) {
                e = ((InvocationTargetException) e).getTargetException();
            }
            if (proceedingJoinPoint != null) {
                Class<?> forName = proceedingJoinPoint.getTarget().getClass();
                className = forName.getSimpleName();
                methodName = proceedingJoinPoint.getSignature().getName();
                String logInfo = StrUtil.format("[{}][{}]:{}", className, methodName, JSON.toJSONString(param));
                if (paramBean != null) {
                    logInfo = StrUtil.format("[{}][{}]:{}", className, methodName, paramBean.toString());
                }
                logger.error(e, logInfo);

            }
            throw e;
        }
        return resultBean;
    }

}
